package com.rachel.cussdk.videosdk;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.SurfaceTexture;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Util;
import com.rachel.cussdk.R;

/**
 * Created by zhengshaorui on 2017/8/26.
 */

public class CusVideoView extends RelativeLayout implements  ExoPlayer.EventListener, TextureView.SurfaceTextureListener, View.OnClickListener, SeekBar.OnSeekBarChangeListener, View.OnTouchListener {
    /**
     * const
     */
    private static final String TAG = "zsr";
    private static final long ANIMATION_TIME = 5000;
    public static final float VIDEO_HEIGHT_PERCENT = 9 / 16.0f;
    public static final float VIDEO_ALPHA = 0.8f;
    public static final int AUTO_DISPEAR_TIME = 2000;
    public static final int AUTO_DISPEAR = 1;
    private static final int UPDATE_CURRENT_STATUS = 2;
    private static final int UPDATE_CURRENT_LOOP_TIME = 100; //每隔100ms刷新一下进度

    // play 状态
    private static final int READY = 0;
    private static final int PLAYING = 1;
    private static final int PAUSE = 2;
    private static final int FINISHED = 3;


    /**
     * ui
     */
    private LinearLayout mLinearLayout;
    private ImageView mVideoImage;
    private TextureView mTextureView;
    private TextView mWholeTiemText;
    private TextView mCurrentTimeText;
    private SeekBar mSeekBar;
    private ProgressBar mLoadingProgress;

    /**
     * logic
     */
    private boolean isFirst = true;
    private int playingStatus ;

    /**
     * varaiable
     */
    private Context mContext;
    private String mSourceUri;
    private SimpleExoPlayer mPlayer;
    private Handler mHandler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case AUTO_DISPEAR:
                    Log.d("zheng", "传上来了？");
                    showBottomAndImgView(mTextureView,VISIBLE);
                    break;
                case UPDATE_CURRENT_STATUS:
                    if (mCurrentTimeText != null && mPlayer != null){
                        String time = ToolUtis.stringForTime(mPlayer.getCurrentPosition());
                        mCurrentTimeText.setText(time);
                        if (mSeekBar != null){
                            mSeekBar.setProgress((int) (mPlayer.getCurrentPosition() * 100 /
                                                            mPlayer.getDuration()));
                        }
                        mHandler.sendEmptyMessageDelayed(UPDATE_CURRENT_STATUS,UPDATE_CURRENT_LOOP_TIME);
                    }
                    break;
            }
        }
    };





    public CusVideoView(Context context) {
        this(context,null);
    }

    public CusVideoView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CusVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        this.removeAllViews();
        View view = LayoutInflater.from(context).inflate(R.layout.cusviedoplayer_layout,null);
        this.addView(view);
        mTextureView = (TextureView) view.findViewById(R.id.videosdk_textureview);
        mTextureView.setOnClickListener(this);
       // mTextureView.setClickable(false);
        mVideoImage = (ImageView) view.findViewById(R.id.videosdk_videoimg);
        mLinearLayout = (LinearLayout) view.findViewById(R.id.videosdk_bottom_ly);
        mWholeTiemText = (TextView) view.findViewById(R.id.videosdk_wholetime);
        mCurrentTimeText = (TextView) view.findViewById(R.id.videosdk_currenttime);
        mSeekBar = (SeekBar) view.findViewById(R.id.videosdk_seekbar);
        mLoadingProgress = (ProgressBar) view.findViewById(R.id.videosdk_loadingprogress);
        mSeekBar.setProgress(0);
        mSeekBar.setOnSeekBarChangeListener(this);
        mSeekBar.setOnTouchListener(this);
        mVideoImage.setOnClickListener(this);
        mTextureView.setSurfaceTextureListener(this);
    }

    /**
     * 设置sourceuri
     * @param uri
     */
    public void setSourceUri(String uri){
        mSourceUri = uri;
        if (uri != null && playingStatus == READY){
            checkPlayer(uri);
            showReadyPlayView();
        }else{
            Toast.makeText(mContext, "uri could not null", Toast.LENGTH_SHORT).show();
            return;
        }
    }



    public void play(){
        if (mPlayer != null ){
            if (mSourceUri != null && playingStatus != PLAYING) {
                mPlayer.setPlayWhenReady(true);
                playingStatus = PLAYING;
            }
        }
    }
    public void pause(){
        if (mSourceUri != null && playingStatus == PLAYING) {
            mPlayer.setPlayWhenReady(false);
            playingStatus = PAUSE;
        }
    }


    /**
     * 设置成16：9的格式
     */
    private void initData() {
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
        int height = (int) (width * VIDEO_HEIGHT_PERCENT);

        LayoutParams params = new LayoutParams(width, height);
        params.addRule(RelativeLayout.CENTER_IN_PARENT);
        mTextureView.setLayoutParams(params);
    }

    /**
     * 初始化 exoplayer
     * @param uri 设置要付款的uri
     */
    private void checkPlayer(String uri) {
        // 1. Create a default TrackSelector 创建一个通道选择器
        if (mPlayer == null) {
            BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
            TrackSelection.Factory videoTrackSelectionFactory =
                    new AdaptiveTrackSelection.Factory(bandwidthMeter);
            TrackSelector trackSelector =
                    new DefaultTrackSelector(videoTrackSelectionFactory);


            // 2. Create the player
            mPlayer = ExoPlayerFactory.newSimpleInstance(mContext, trackSelector);


            // Produces DataSource instances through which media data is loaded.
            DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(mContext,
                    Util.getUserAgent(mContext, "测试"), (TransferListener<? super DataSource>) bandwidthMeter);

            // Produces Extractor instances for parsing the media data.
            ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
            // This is the MediaSource representing the media to be played.
            MediaSource videoSource = new ExtractorMediaSource(
                    Uri.parse(uri),
                    //Uri.parse("http://www.wooyun.site/1987.mp4"),
                    dataSourceFactory,
                    extractorsFactory,
                    null,
                    null);
            // Prepare the player with the source.
            mPlayer.prepare(videoSource);
        }

        mPlayer.addListener(this);
        // 3.binder the player to the view
        mPlayer.setVideoTextureView(mTextureView);


    }

    /**
     * 释放exoplayer
     */
    public void releaseMedia(){
        if (mPlayer != null){
            mPlayer.stop();
            mPlayer.release();
            mTextureView = null;

        }
    }



    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest) {
        Log.d(TAG, "onTimelineChanged: "+timeline);
        String wholetime = ToolUtis.stringForTime(mPlayer.getDuration());
        Log.d(TAG, "onLoadingChanged: "+mPlayer.getDuration()+" "+wholetime);
        mWholeTiemText.setText(wholetime);
        mCurrentTimeText.setText(ToolUtis.stringForTime(mPlayer.getCurrentPosition()));
        mHandler.sendEmptyMessageDelayed(UPDATE_CURRENT_STATUS,UPDATE_CURRENT_LOOP_TIME);

    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
        Log.d(TAG, "onTracksChanged: ");
    }

    @Override
    public void onLoadingChanged(boolean isLoading) {
        Log.d(TAG, "onLoadingChanged: "+isLoading);
        if (!isLoading){ //loading 完毕

        }
    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        Log.d(TAG, "onPlayerStateChanged: "+playbackState+" "+ExoPlayer.STATE_ENDED);
        if (playbackState == ExoPlayer.STATE_ENDED){ //播放完成
            playingStatus = FINISHED;
            showBottomAndImgView(mTextureView,GONE);

        }
        //缓存ok
        if (playbackState == ExoPlayer.STATE_READY){
            showLoadingProgress(false);
        }
        //缓存阶段
        if (playbackState == ExoPlayer.STATE_BUFFERING){
            showLoadingProgress(true);
        }
    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {
        Log.d(TAG, "onPlayerError: "+error);
    }

    @Override
    public void onPositionDiscontinuity() {
        Log.d(TAG, "onPositionDiscontinuity: ");
    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
        Log.d(TAG, "onPlaybackParametersChanged: "+playbackParameters);
    }



    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        playingStatus = READY;
        initData();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        Log.d(TAG, "onSurfaceTextureSizeChanged: "+width+" "+height);
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        Log.d(TAG, "onSurfaceTextureUpdated: ");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.videosdk_videoimg:
                showImageClickView();
                break;
            case R.id.videosdk_textureview:
                int isBottomVisiable = mLinearLayout.getVisibility();
                showBottomAndImgView(mTextureView,isBottomVisiable);
                break;

        }
    }


    private void showImageClickView() {
        int visiable = mLinearLayout.getVisibility();
        Log.d("zheng", "showImageClickView: "+playingStatus);
        // 视频准备好，第一次点击
        if (playingStatus == READY){
            play();
        }else if (playingStatus == PLAYING){//在视频播放的情况下，点击屏幕
            pause();
        }else if (playingStatus == PAUSE){ //在视频暂停的情况下，点击屏幕
            play();
        }else if (playingStatus == FINISHED){
            mPlayer.seekTo(0);
            play();
        }
        Log.d("zheng", "showImageClickView: "+playingStatus);
        showBottomAndImgView(mVideoImage,visiable);
    }

    /**
     * 显示底部状态栏和中间的图片
     * @param isBottomVisiable
     */
    private void showBottomAndImgView(View v,int isBottomVisiable) {
        mHandler.removeMessages(AUTO_DISPEAR);
        if (v.getId() == R.id.videosdk_videoimg){
            if (playingStatus == READY){
                mVideoImage.setImageResource(R.mipmap.start_video);
            }else if (playingStatus == PLAYING) {
                mVideoImage.setImageResource(R.mipmap.pause_video);
            } else if (playingStatus == FINISHED){
                mVideoImage.setImageResource(R.mipmap.videosdk_reload);
            }else {
                mVideoImage.setImageResource(R.mipmap.start_video);
            }
            if (playingStatus == PLAYING) {
                mHandler.sendEmptyMessageDelayed(AUTO_DISPEAR, AUTO_DISPEAR_TIME);
            }
        }else if (v.getId() == R.id.videosdk_textureview){
            if (isBottomVisiable == GONE){
                mLinearLayout.setVisibility(VISIBLE);
                mVideoImage.setVisibility(VISIBLE);
                mTextureView.setAlpha(VIDEO_ALPHA);
                if (playingStatus == FINISHED){
                    mVideoImage.setImageResource(R.mipmap.videosdk_reload);
                }
            }else{
                mLinearLayout.setVisibility(GONE);
                mVideoImage.setVisibility(GONE);
                mTextureView.setAlpha(1);
            }
        }

        if (playingStatus == PLAYING){
            Log.d("zheng", "showBottomAndImgView: "+playingStatus);
            mHandler.sendEmptyMessageDelayed(AUTO_DISPEAR,AUTO_DISPEAR_TIME);
        }


    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (mPlayer != null){
            long seekTime = progress * mPlayer.getDuration() / 100;
            mCurrentTimeText.setText(ToolUtis.stringForTime(seekTime));

        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        long seekTime = seekBar.getProgress() * mPlayer.getDuration() / 100;
        mPlayer.seekTo(seekTime);
    }

    /**
     * 隐藏progress
     * @param ishide
     */
    private void showLoadingProgress(boolean ishide){
        Log.d(TAG, "showLoadingProgress: "+mLoadingProgress);
        if (mLoadingProgress != null){
            if (ishide){
                mLoadingProgress.setVisibility(View.VISIBLE);
            }else{
                mLoadingProgress.setVisibility(View.GONE);
            }
        }
    }

    /**
     * 显示视频准备好的图片图片
     */
    private void showReadyPlayView() {
        mHandler.removeCallbacksAndMessages(null);
        mLinearLayout.setVisibility(VISIBLE);
        mVideoImage.setVisibility(VISIBLE);
        mVideoImage.setImageResource(R.mipmap.start_video);
        mTextureView.setAlpha(VIDEO_ALPHA);
    }

    /**
     * @param v
     * @param event
     * @return
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (v.getId()){
            case  R.id.videosdk_seekbar:
                switch (event.getAction()){

                    case MotionEvent.ACTION_MOVE:
                        mHandler.removeCallbacksAndMessages(null);
                        break;
                    case MotionEvent.ACTION_UP:
                        mHandler.sendEmptyMessageDelayed(AUTO_DISPEAR,AUTO_DISPEAR_TIME);
                        mHandler.sendEmptyMessageDelayed(UPDATE_CURRENT_STATUS,UPDATE_CURRENT_LOOP_TIME);
                        break;
                }
                break;
        }
        return false;
    }

    private void registerBroadcastReceiver() {
        /*if (mScreenReceiver == null) {
            mScreenReceiver = new ScreenEventReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(Intent.ACTION_USER_PRESENT);
            getContext().registerReceiver(mScreenReceiver, filter);
        }*/
    }

    private void unRegisterBroadcastReceiver() {
       /* if (mScreenReceiver != null) {
            getContext().unregisterReceiver(mScreenReceiver);
        }*/
    }

    /**
     * 监听锁屏事件的广播接收器
     */
    private class ScreenEventReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //主动锁屏时 pause, 主动解锁屏幕时，resume
            switch (intent.getAction()) {
                case Intent.ACTION_USER_PRESENT:

                    break;
                case Intent.ACTION_SCREEN_OFF:

                    break;
            }
        }
    }
}
